package mh.map;

import org.lwjgl.opengl.GL11;

/**
 * A texture to be bound within JOGL. This object is responsible for keeping track of a given OpenGL texture and for
 * calculating the texturing mapping coordinates of the full image.
 * 
 * Since textures need to be powers of 2 the actual texture may be considerably bigger that the source image and hence
 * the texture mapping coordinates need to be adjusted to matchup drawing the sprite against the texture.
 * 
 * @author Kevin Glass
 * @author Brian Matzon
 */
public class Texture {
	/** The GL target type */
	private final int	target;
	/** The GL texture ID */
	private final int	textureID;
	/** The height of the image */
	private int			height;
	/** The width of the image */
	private int			width;
	/** The width of the texture */
	private int			texWidth;
	/** The height of the texture */
	private int			texHeight;
	/** The ratio of the width of the image to the texture */
	private float		widthRatio;
	/** The ratio of the height of the image to the texture */
	private float		heightRatio;

	/**
	 * Create a new texture
	 * 
	 * @param target
	 *            The GL target
	 * @param textureID
	 *            The GL texture ID
	 */
	public Texture(int target, int textureID) {
		this.target = target;
		this.textureID = textureID;
	}

	/**
	 * Set the correct dimensions of the texture (ratio) if the original image is not perfectly cuttable in exact parts.
	 * Bottom and right excedence are not used.
	 * 
	 * @param width
	 * @param height
	 */
	public void cut(int width, int height) {
		this.width = width;
		this.setWidth();
		this.height = height;
		this.setHeight();
	}

	/**
	 * Bind the specified GL context to a texture
	 */
	public void bind() {
		GL11.glBindTexture(this.target, this.textureID);
	}

	/**
	 * Set the height of the image
	 * 
	 * @param height
	 *            The height of the image
	 */
	public void setHeight(int height) {
		this.height = height;
		this.setHeight();
	}

	/**
	 * Set the width of the image
	 * 
	 * @param width
	 *            The width of the image
	 */
	public void setWidth(int width) {
		this.width = width;
		this.setWidth();
	}

	/**
	 * Get the height of the original image
	 * 
	 * @return The height of the original image
	 */
	public int getImageHeight() {
		return this.height;
	}

	/**
	 * Get the width of the original image
	 * 
	 * @return The width of the original image
	 */
	public int getImageWidth() {
		return this.width;
	}

	/**
	 * Get the height of the physical texture
	 * 
	 * @return The height of physical texture
	 */
	public float getHeight() {
		return this.heightRatio;
	}

	/**
	 * Get the width of the physical texture
	 * 
	 * @return The width of physical texture
	 */
	public float getWidth() {
		return this.widthRatio;
	}

	/**
	 * Set the height of this texture
	 * 
	 * @param texHeight
	 *            The height of the texture
	 */
	public void setTextureHeight(int texHeight) {
		this.texHeight = texHeight;
		this.setHeight();
	}

	/**
	 * Set the width of this texture
	 * 
	 * @param texWidth
	 *            The width of the texture
	 */
	public void setTextureWidth(int texWidth) {
		this.texWidth = texWidth;
		this.setWidth();
	}

	/**
	 * Set the height of the texture. This will update the ratio also.
	 */
	private void setHeight() {
		if (this.texHeight != 0) {
			this.heightRatio = ((float) this.height) / this.texHeight;
		}
	}

	/**
	 * Set the width of the texture. This will update the ratio also.
	 */
	private void setWidth() {
		if (this.texWidth != 0) {
			this.widthRatio = ((float) this.width) / this.texWidth;
		}
	}
}
